<script setup name="User">
import {getUserPageList, resetUserPwd, delUser, getUser, updateUser, addUser} from "@/api/system/user.js"
import {getDeptTree} from "@/api/system/dept.js"
import {getToken} from '@/utils/auth'
import {getRoleAllList} from "@/api/system/role.js";
import {validateRegExp} from "@/utils/ruoyi.js";
import useAppStore from "@/store/modules/app.js";

const device = computed(() => useAppStore().device);
const {proxy} = getCurrentInstance()
const {userStatus, gender} = proxy.useDict(["userStatus", true], ["gender", false])
const userList = ref([])
const open = ref(false)
const loading = ref(true)
const showSearch = ref(true)
const total = ref(0)
const title = ref("")
const deptName = ref("")
const deptOptions = ref(undefined)
const roleOptions = ref([])
/*** 用户导入参数 */
const upload = reactive({
  // 是否显示弹出层（用户导入）
  open: false,
  // 弹出层标题（用户导入）
  title: "",
  // 是否禁用上传
  isUploading: false,
  // 是否更新已经存在的用户数据
  updateSupport: 0,
  // 设置上传的请求头部
  headers: {token: getToken()},
  // 上传的地址
  url: import.meta.env.VITE_APP_BASE_API + "/system/userManage/importExcel"
})
// 列显隐信息
const columns = ref({
  username: {key: 'username', label: `用户名`, visible: true},
  nickName: {key: 'nickName', label: `真实姓名`, visible: true},
  sex: {key: 'sex', label: `性别`, visible: false},
  deptName: {key: 'deptName', label: `隶属部门`, visible: true},
  duty: {key: 'duty', label: `职务`, visible: false},
  phoneNumber: {key: 'phoneNumber', label: `手机号码`, visible: true},
  email: {key: 'email', label: `邮箱`, visible: false},
  status: {key: 'status', label: `状态`, visible: true},
  roles: {key: 'roles', label: `角色`, visible: true},
  updateTime: {key: 'updateTime', label: '修改时间', visible: false},
  createTime: {key: 'createTime', label: `创建时间`, visible: false}
})
const data = reactive({
  form: {},
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    nickName: undefined,
    phoneNumber: undefined,
    status: undefined,
    deptId: undefined
  },
  rules: {
    username: [{ required: true, message: "用户名不能为空", trigger: "blur" }],
    nickName: [{ required: true, message: "真实姓名不能为空", trigger: "blur" }],
    password: [{ required: true, message: "用户密码不能为空", trigger: "blur" }],
    email: [{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }],
    phoneNumber: [{required: true, pattern: validateRegExp.phoneNum.regExp, message: validateRegExp.phoneNum.message, trigger: "blur" }],
    memo: [{ max: 255, message: "备注内容长度不能超过 255 个字符", trigger: "blur" }]
  }
})
const {queryParams, form, rules} = toRefs(data)

onMounted(() => {
  getDeptTreeInfo()
  getList()
})

const statusStyles = {
  '新建': 'info',
  '启用': 'success',
  '暂停': 'warning',
  '离职': 'danger'
}
const getTagType = function (status) {
  return statusStyles[status] || 'info';
}

/** 通过条件过滤节点  */
const filterNode = (value, data) => {
  if (!value) return true
  return data.name.indexOf(value) !== -1
}
/** 根据名称筛选部门树 */
watch(deptName, val => {
  proxy.$refs["deptTreeRef"].filter(val)
})

/** 查询部门下拉树结构 */
function getDeptTreeInfo() {
  getDeptTree().then(list => {
    deptOptions.value = list
  })
}

/** 查询用户列表 */
function getList() {
  loading.value = true
  getUserPageList(queryParams.value).then(res => {
    loading.value = false
    userList.value = res.list
    total.value = res.total
  })
}

/** 节点单击事件 */
function handleNodeClick(data) {
  queryParams.value.deptId = data.id
  handleQuery()
}

/** 搜索按钮操作 */
function handleQuery() {
  queryParams.value.pageNum = 1
  getList()
}

/** 重置按钮操作 */
function resetQuery() {
  proxy.resetForm("queryRef")
  queryParams.value.deptId = undefined
  proxy.$refs.deptTreeRef.setCurrentKey(null)
  handleQuery()
}

/** 删除按钮操作 */
function handleDelete(row) {
  proxy.$modal.confirmAndExecuteJS('是否确认删除真实姓名为"' + row.nickName + '"的用户记录?', delUser, row.id, getList)
}

/** 重置密码按钮操作 */
function handleResetPwd(row) {
  proxy.$modal.confirm('是否确认将真实姓名为"' + row.nickName + '"的用户密码重置为6个1？').then(function () {
    resetUserPwd(row.id).then(() => {
      proxy.$modal.msgSuccess("密码重置成功，新密码是：111111")
    })
  }).catch(() => {})
}

/** 下载模板操作 */
function importTemplate() {
  proxy.download("/system/userManage/getImportTemplate", {
  }, `user_template_${new Date().getTime()}.xlsx`)
}

/** 导入按钮操作 */
function handleImport() {
  upload.title = "用户导入"
  upload.open = true
}
/**文件上传中处理 */
const handleFileUploadProgress = () => {
  upload.isUploading = true
}
/** 文件上传成功处理 */
const handleFileSuccess = (response, file) => {
  const code = response.code
  let tipMsg
  if ('200' !== code) {
    tipMsg = response.message
  } else {
    const data = response.result
    const createLength = data.createUsernames.length
    const updateLength = data.updateUsernames.length
    const failureLength = Object.keys(data.failureUsernames).length
    tipMsg = (createLength > 0) ? '<p>上传成功，数量：' + createLength + '；<p style="text-indent: 2em;">' : ''
    for (let username of data.createUsernames) {
      tipMsg += '< ' + username + ' > '
    }
    tipMsg += (createLength > 0) ? '</p></p>' : '</p>'

    tipMsg += (updateLength > 0) ? '<p>更新成功，数量：' + updateLength + '；<p style="text-indent: 2em;">' : ''
    for (const username of data.updateUsernames) {
      tipMsg += '< ' + username + ' > '
    }
    tipMsg += (updateLength > 0) ? '</p></p>' : '</p>'

    tipMsg += (failureLength > 0) ? '<p>更新失败，数量：' + failureLength + '；<p style="text-indent: 2em;">' : ''
    for (const username in data.failureUsernames) {
      tipMsg += '< ' + username + '：' + data.failureUsernames[username] + ' > '
    }
    tipMsg += (failureLength > 0) ? '</p></p>' : '</p>'
    upload.open = false

    getList()
  }
  upload.isUploading = false
  proxy.$refs["uploadRef"].handleRemove(file)
  proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + tipMsg + "</div>", "导入结果", { dangerouslyUseHTMLString: true })
}
const handleFileFail = () => {
  upload.isUploading = false
}

/** 提交上传文件 */
function submitFileForm() {
  proxy.$refs["uploadRef"].submit()
}

/** 重置操作表单 */
function reset() {
  form.value = {
    id: undefined,
    deptId: undefined,
    username: undefined,
    nickName: undefined,
    phoneNumber: undefined,
    email: undefined,
    sex: '男',
    status: '新建',
    memo: undefined,
    duty: undefined,
    roleIds: []
  }
  proxy.resetForm("userRef")
}

/** 取消按钮 */
function cancel() {
  open.value = false
  reset()
}

/** 新增按钮操作 */
function handleAdd() {
  reset()
  open.value = true
  title.value = "添加用户"
  getRoleAllList().then(list => {
    roleOptions.value = list
  })
}

/** 修改按钮操作 */
function handleUpdate(row) {
  reset()
  const userId = row.id
  getUser(userId).then(user => {
    form.value = user
    open.value = true
    title.value = "修改用户"
  })
  getRoleAllList().then(list => {
    roleOptions.value = list
  })
}

/** 提交按钮 */
function submitForm() {
  proxy.$refs["userRef"].validate(valid => {
    if (valid) {
      if (form.value.id !== undefined) {
        updateUser(form.value).then(() => {
          proxy.$modal.msgSuccess("修改成功")
          open.value = false
          getList()
        })
      } else {
        addUser(form.value).then(() => {
          proxy.$modal.msgSuccess("新增成功")
          open.value = false
          getList()
        })
      }
    }
  })
}

</script>

<template>
  <div class="app-container">
    <el-row :gutter="20">
      <!--部门数据-->
      <el-col :span="4" :xs="24">
        <div class="head-container">
          <el-input
              v-model="deptName"
              placeholder="请输入部门名称"
              clearable
              prefix-icon="Search"
              style="margin-bottom: 20px"
          />
        </div>
        <div class="head-container">
          <el-tree
              :data="deptOptions"
              :props="{label: 'name' }"
              :expand-on-click-node="false"
              :filter-node-method="filterNode"
              ref="deptTreeRef"
              node-key="id"
              highlight-current
              default-expand-all
              @node-click="handleNodeClick"
          >
            <template #default="{ node, data }">
              <el-tooltip class="item" effect="dark" :content="node.label" placement="top-start">
                <span class="custom-tree-scrollbar"> {{ node.label }} </span>
              </el-tooltip>
            </template>
          </el-tree>
        </div>
      </el-col>
      <!--用户数据-->
      <el-col :span="20" :xs="24" :class="{'mt20': device === 'mobile'}">
        <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
          <el-form-item label="真实姓名" prop="nickName">
            <el-input
                v-model="queryParams.nickName"
                placeholder="请输入真实姓名"
                clearable
                style="width: 200px"
                @keyup.enter="handleQuery"
            />
          </el-form-item>
          <el-form-item label="手机号码" prop="phoneNumber">
            <el-input
                v-model="queryParams.phoneNumber"
                placeholder="请输入手机号码"
                clearable
                style="width: 200px"
                @keyup.enter="handleQuery"
            />
          </el-form-item>
          <el-form-item label="状态" prop="status">
            <el-select
                v-model="queryParams.status"
                placeholder="用户状态"
                clearable
                style="width: 200px"
                :empty-values="[null, undefined]"
            >
              <el-option
                  v-for="dict in userStatus"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
            <el-button icon="Refresh" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>

        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button
                type="primary"
                plain
                icon="Plus"
                @click="handleAdd"
                v-hasPermi="['system:userManage:add']"
            >新增
            </el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
                type="info"
                plain
                icon="Upload"
                @click="handleImport"
                v-hasPermi="['system:userManage:importExcel']"
            >导入
            </el-button>
          </el-col>
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns" v-show="total > 0"></right-toolbar>
        </el-row>

        <el-table v-loading="loading" :data="userList">
          <el-table-column :label="columns.username.label" key="username" prop="username" v-if="columns.username.visible" width="150" :show-overflow-tooltip="true" />
          <el-table-column :label="columns.nickName.label" key="nickName" prop="nickName" v-if="columns.nickName.visible" width="150" :show-overflow-tooltip="true" />
          <el-table-column :label="columns.sex.label" key="sex" prop="sex" v-if="columns.sex.visible" width="60"  :show-overflow-tooltip="true" />
          <el-table-column :label="columns.deptName.label" key="deptName" prop="deptName" v-if="columns.deptName.visible" width="250" :show-overflow-tooltip="true" />
          <el-table-column :label="columns.duty.label" key="duty" prop="duty" v-if="columns.duty.visible" width="150" :show-overflow-tooltip="true" />
          <el-table-column :label="columns.phoneNumber.label" key="phoneNumber" prop="phoneNumber" v-if="columns.phoneNumber.visible" width="130" />
          <el-table-column :label="columns.email.label" key="email" prop="email" v-if="columns.email.visible" width="220" :show-overflow-tooltip="true" />
          <el-table-column :label="columns.status.label" key="status" prop="status" v-if="columns.status.visible" width="60">
            <template #default="scope">
              <el-text :type="getTagType(scope.row.status)"> {{ scope.row.status }} </el-text>
            </template>
          </el-table-column>
          <el-table-column :label="columns.roles.label" key="roles" prop="roles" v-if="columns.roles.visible" :show-overflow-tooltip="true"/>
          <el-table-column :label="columns.updateTime.label" key="updateTime" prop="updateTime" v-if="columns.updateTime.visible" width="160" />
          <el-table-column :label="columns.createTime.label" key="createTime" prop="createTime" v-if="columns.createTime.visible" width="160" />
          <el-table-column label="操作" align="left" fixed="right" class-name="small-padding" :width="device === 'mobile' ? '160' : '230'">
            <template #default="scope">
              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:userManage:update']" v-if="scope.row.id !== 1">修改</el-button>
              <el-button link type="primary" icon="Key" @click="handleResetPwd(scope.row)" v-hasPermi="['system:userManage:resetPwd']"  v-if="scope.row.id !== 1">重置密码</el-button>
              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:userManage:delete']" v-if="(scope.row.id !== 1) && scope.row.status==='新建'">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <pagination
            v-show="total > 0"
            :total="total"
            v-model:page="queryParams.pageNum"
            v-model:limit="queryParams.pageSize"
            @pagination="getList"
        />
      </el-col>
    </el-row>

    <!-- 添加或修改用户配置对话框 -->
    <el-dialog :title="title" v-model="open" width="800px" append-to-body :close-on-click-modal="false">
      <el-form :model="form" :rules="rules" ref="userRef" label-width="80px">
        <el-row :gutter="10">
          <el-col :span="12">
            <el-form-item label="真实姓名" prop="nickName">
              <el-input v-model="form.nickName" placeholder="请输入真实姓名" maxlength="30" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="用户名" prop="username">
              <el-input v-model="form.username" placeholder="请输入用户用户名" maxlength="50" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="12">
            <el-form-item label="手机号码" prop="phoneNumber">
              <el-input v-model="form.phoneNumber" placeholder="请输入手机号码" maxlength="11" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="邮箱" prop="email">
              <el-input v-model="form.email" placeholder="请输入邮箱地址" maxlength="50" />
            </el-form-item>
          </el-col>

        </el-row>
        <el-row :gutter="10">
          <el-col :span="12">
            <el-form-item label="密码">
              <el-input placeholder="用户的初始密码均为6个1" disabled/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="性别">
              <el-select v-model="form.sex" placeholder="请选择">
                <el-option
                    v-for="dict in gender"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="12">
            <el-form-item label="隶属部门">
              <el-tree-select
                  v-model="form.deptId"
                  :data="deptOptions"
                  :props="{ value: 'id', label: 'name', children: 'children' }"
                  value-key="id"
                  placeholder="请选择隶属部门"
                  check-strictly
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="职位" prop="duty">
              <el-input v-model="form.duty" placeholder="请输入员工职位" maxlength="100" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="12" v-if="form.id">
            <el-form-item label="状态">
              <el-select v-model="form.status" placeholder="请选择">
                <el-option
                    v-for="dict in userStatus"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                    :disabled="dict.value===form.status"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="角色">
              <el-select v-model="form.roleIds" multiple placeholder="请选择">
                <el-option
                    v-for="item in roleOptions"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="备注">
              <el-input v-model="form.memo" type="textarea" placeholder="请输入内容" maxlength="255"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <!--用户导入对话框-->
    <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body :close-on-click-modal="false">
      <el-upload
          ref="uploadRef"
          :limit="1"
          accept=".xlsx, .xls"
          :headers="upload.headers"
          :action="upload.url + '?updateSupport=' + upload.updateSupport"
          :disabled="upload.isUploading"
          :on-progress="handleFileUploadProgress"
          :on-success="handleFileSuccess"
          :on-error="handleFileFail"
          :auto-upload="false"
          drag
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        <template #tip>
          <div class="el-upload__tip text-center">
            <div class="el-upload__tip">
              <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据
            </div>
            <span>仅允许导入xls、xlsx格式文件。</span>
            <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
          </div>
        </template>
      </el-upload>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitFileForm">确 定</el-button>
          <el-button @click="upload.open = false">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.custom-tree-scrollbar {
  width: 100%;
  overflow: hidden !important;
  white-space: nowrap !important;
  text-overflow: ellipsis !important;
  display: block !important;
}
</style>
